/**
 * {作业名称}
 *
 * 输入参数:
 *
 * 输出参数:
 *
 */
(() => {
  // 私有区域
  const LdapConnection = Host.type('Novell.Directory.Ldap.LdapConnection', 'Novell.Directory.Ldap.NETStandard');
  const expires = 3600;   // Token1小时过期

  return function ({ UID, User, Password, redirect_uri }, headers) {
    // 验证输入参数
    const real_ip = (headers['X-Real-IP'] || []).join(',');
    const card_用户 = A.card('B.用户');
    const card_登录审计 = A.card('B.登录审计');

    const { rows } = A.db.execute(card_用户.连接名称, "SELECT ID,TY FROM B_YH WHERE YHM=?", [User]);
    if (rows.length === 0) {
      card_登录审计.save({
        用户名: User,
        来源地址: real_ip,
        是否通过: 0
      }, UID);
      throw Error("用户名不存在");
    }
    if (rows[0].TY === 1) {
      card_登录审计.save({
        用户名: User,
        来源地址: real_ip,
        是否通过: 0
      }, UID);
      throw Error("用户已停用");
    }

    // 处理逻辑
    const host = A.setting('LDAP.Server');
    const port = Number(A.setting('LDAP.Port') || 389);
    const baseDN = A.setting('LDAP.BaseDN');
    const ssl = A.setting('LDAP.Ssl');

    const ldapConnection = new LdapConnection();
    ldapConnection.SecureSocketLayer = !!ssl;

    try {
      ldapConnection.Connect(host, port);
      ldapConnection.Bind(`cn=${User},${baseDN}`, Password);
      if (!ldapConnection.Bound) throw Error('Bind fail');
    } catch (e) {
      card_登录审计.save({
        用户名: User,
        来源地址: real_ip,
        是否通过: 0
      }, UID);
      throw Error('登录失败: ' + e.message);
    } finally {
      ldapConnection.Dispose();
    }

    // 返回结果
    const token = A.jwt.create({
      UID: rows[0].ID,
      IP: real_ip,
    }, expires);

    card_登录审计.save({
      用户名: User,
      来源地址: real_ip,
      是否通过: 1
    }, UID);

    return { token, expires, redirect_uri };
  };
})()